package com.hotelsystem.reservations.reservations;

import java.io.File;
import java.util.Arrays;

/**
 * Class providing functionality for moving reservation files from 
 * directory with future reservations to directory with current reservations
 *
 * @author Peter Lazarov
 *
 */
public class ReservationsScheduler {

	/**
	 * Number of threads which check if the reservation is become current
	 * and if so moves it to another location
	 */
	protected int threadCount;
	/**
	 * The interval(in milliseconds) on how often to execute the code
	 */
	protected long timeInterval;
	/**
	 * Directory with the future reservations
	 */
	protected String sourceDirectory;
	/**
	 * Directory with the current reservations
	 */
	protected String destinationDirectory;

	/**
	 * Constructor for FutureReservationsScheduler class
	 * @param timeInterval - time in milliseconds for scheduler to sleep
	 */
	public ReservationsScheduler(long timeInterval, String sourceDirectory, String destinationDirectory) {
		this.timeInterval = timeInterval;
		this.sourceDirectory = sourceDirectory;
		this.destinationDirectory = destinationDirectory;
	}

	/**
	 * Method to start the background thread which work parallel with the main thread
	 * Call the goOverFiles method which loop over files in the source directory 
	 */
	public void startMechanisme() {

		Thread backgroundThread = new Thread(new Runnable() {

			@Override
			public void run() {
				while (true) {
					goOverFiles();
					try {
						Thread.sleep(timeInterval);
					} catch (InterruptedException e) {
						System.out.println("Problem with interrupted thread!");
						e.printStackTrace();
					}
				}
			}

		});
		backgroundThread.start();
	}
	
	/**
	 * Loops over files in the source directory
	 * Creates number of threads according to the number of reservation in the source folder
	 * Every thread is created with parameter - array of files (portion of file to check)
	 */
	
	protected void goOverFiles() {
		String sourcePath = sourceDirectory;		
		File sourceFolder = new File(sourcePath);
		File[] files = sourceFolder.listFiles();
		
		if (files.length < 10) {
			threadCount = files.length;
		} else {
			threadCount = 10;
		}

		if (threadCount != 0) {
			int portion = files.length / threadCount;
			int remainder = files.length % threadCount;

			if (remainder != 0) {
				threadCount++;
			}


			int lowerBound = 0;
			int upperBound = 0;

			File[] portionArray;
			for (int i = 0; i < threadCount; i++) {
				
				if (i == threadCount - 1 && remainder != 0) {
					lowerBound = files.length - remainder;
					upperBound = files.length;
				} else {
					lowerBound = i * portion;
					upperBound = (i + 1) * portion;
				}
				portionArray = Arrays.copyOfRange(files, lowerBound, upperBound);
				spawnWorkers(portionArray, lowerBound, upperBound);
				
			}
		}
		
	}
	/**
	 * THIS METOD MUST BE OVERRIDDEN!
	 * It should create the appropriate type of worker threads depending on which scheduler calls it
	 * @param files
	 * @param lowerBound
	 * @param upperBound
	 */
	protected void spawnWorkers(File[] files, int lowerBound, int upperBound) {

	}
	
}
